﻿#region License

// PentaBiz - Sustainable Software Development Framework Copyright (C) 2013 Zoltán Csizmazia
// 
// This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using AvalonDock;
using AvalonDock.Themes;
using PentaBiz.ComponentModel;
using PentaBiz.WpfTools;

namespace PentaBiz.Studio.Application.Themes
{
    internal class ThemeManager : DependencyObject
    {
        public static readonly DependencyProperty SelectedThemeProperty =
            DependencyProperty.Register("SelectedTheme", typeof (Theme), typeof (ThemeManager),
                                        new PropertyMetadata(default(Theme)));

        private static readonly DependencyPropertyKey SelectThemeCommandPropertyKey =
            DependencyProperty.RegisterReadOnly("SelectThemeCommand", typeof (ICommand), typeof (ThemeManager),
                                                new PropertyMetadata(default(ICommand)));

        public static DependencyProperty SelectThemeCommandProperty = SelectThemeCommandPropertyKey.DependencyProperty;

        private readonly Black _blackTheme = new Black();
        private readonly Blue _blueTheme = new Blue();
        private readonly ShellViewModel _shellViewModel;
        private readonly Silver _silverTheme = new Silver();


        public ThemeManager(ShellViewModel shellViewModel)
        {
            _shellViewModel = shellViewModel;
            SelectedTheme = BlackTheme;
            SelectThemeCommand = new RelayCommand(o => SelectThemeCommandAction(o as Theme),
                                                  o => SelectThemeCommandCondition(o as Theme));
        }

        public Theme SelectedTheme
        {
            get { return (Theme) GetValue(SelectedThemeProperty); }
            set { SetValue(SelectedThemeProperty, value); }
        }


        public ICommand SelectThemeCommand
        {
            get { return (ICommand) GetValue(SelectThemeCommandProperty); }
            private set { SetValue(SelectThemeCommandPropertyKey, value); }
        }

        public Blue BlueTheme
        {
            get { return _blueTheme; }
        }

        public Black BlackTheme
        {
            get { return _blackTheme; }
        }

        public Silver SilverTheme
        {
            get { return _silverTheme; }
        }

        private void SelectThemeCommandAction(Theme theme)
        {
            SelectedTheme = theme;
            SelectedTheme.ApplyTheme();

            //_shellViewModel.PluginManager.Plugins.First().

            //foreach (var plugin in _shellViewModel.PluginManager.Plugins)
            //{
            //    plugin.View.Resources.BeginInit();

            //    plugin.View.Resources.MergedDictionaries.Clear();

            //    foreach (var resourceDictionary in SelectedTheme.ResourceDictionaries)
            //    {
            //        plugin.View.Resources.MergedDictionaries.Add(resourceDictionary);
            //    }

            //    plugin.View.Resources.EndInit();
            //}
        }

        private bool SelectThemeCommandCondition(Theme theme)
        {
            return theme != null;
        }

        public void Initialize()
        {
        }

        public class Black : Theme
        {
            public Black()
            {
                Name = "Black";
                IconSource =
                    "pack://application:,,,/PentaBiz.Studio.Application;component/Resources/Images/BlackTheme.png";
                ResourceDictionaries = new List<ResourceDictionary>
                    {
                        GetThemeResourceDictionary("Fluent", "Themes/Office2010/Black.xaml"),
                        GetThemeResourceDictionary("PentaBiz.Studio.Application", "Themes/BureauBlack/Theme.xaml"),
                    };
                AvalonDockTheme = new ExpressionDarkTheme();
            }
        }

        public class Blue : Theme
        {
            public Blue()
            {
                Name = "Blue";
                IconSource =
                    "pack://application:,,,/PentaBiz.Studio.Application;component/Resources/Images/BlueTheme.png";
                ResourceDictionaries = new List<ResourceDictionary>
                    {
                        GetThemeResourceDictionary("Fluent", "Themes/Office2010/Blue.xaml"),
                        GetThemeResourceDictionary("PentaBiz.Studio.Application", "Themes/BureauBlue/Theme.xaml"),
                    };
                AvalonDockTheme = new VS2010Theme();
            }
        }

        public class Silver : Theme
        {
            public Silver()
            {
                Name = "Silver";
                IconSource =
                    "pack://application:,,,/PentaBiz.Studio.Application;component/Resources/Images/SilverTheme.png";
                ResourceDictionaries = new List<ResourceDictionary>
                    {
                        GetThemeResourceDictionary("Fluent", "Themes/Office2010/Silver.xaml"),
                        GetThemeResourceDictionary("PentaBiz.Studio.Application", "Themes/ExpressionLight/Theme.xaml"),
                    };
                AvalonDockTheme = new ExpressionLightTheme();
            }
        }

        public abstract class Theme : DispatcherObject
        {
            public IEnumerable<ResourceDictionary> ResourceDictionaries { get; set; }
            public AvalonDock.Themes.Theme AvalonDockTheme { get; set; }

            public string Name { get; set; }
            public string IconSource { get; set; }

            public void ApplyTheme()
            {
                Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (ThreadStart) (ApplyThemePrivate));
            }

            private void ApplyThemePrivate()
            {
                System.Windows.Application.Current.Resources.BeginInit();
                System.Windows.Application.Current.Resources.MergedDictionaries.Clear();

                foreach (var resourceDictionary in ResourceDictionaries)
                {
                    System.Windows.Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
                }

                System.Windows.Application.Current.Resources.EndInit();
            }


            public static ResourceDictionary GetThemeResourceDictionary(string assembly, string component)
            {
                if (component != null)
                {
                    //Assembly assembly = Assembly.LoadFrom("WPF.Themes.dll");
                    string packUri = String.Format(@"/{0};component/{1}", assembly, component);
                    return
                        System.Windows.Application.LoadComponent(new Uri(packUri, UriKind.Relative)) as
                        ResourceDictionary;
                }
                return null;
            }
        }
    }
}